package com.knife.easyexcel.write.handler;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.knife.common.utils.KnifeSpringUtil;
import com.knife.easyexcel.write.annotation.SpinnerData;
import com.knife.easyexcel.write.supplier.EasyExcelSpinnerDataSupplier;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 添加下拉框，参考https://blog.csdn.net/qq_20448967/article/details/103581419
 *
 * @author： 76875
 * @date： 2022/5/25 星期三 23:34
 * @description：
 * @modifiedBy：
 * @version: 1.0
 */
public class SpinnerWriteHandler implements SheetWriteHandler {


    /**
     * 导出的实体模板类型
     */
    private final Class<?> templateClass;

    public SpinnerWriteHandler(Class<?> templateClass) {
        this.templateClass = templateClass;
    }

    private String[] readySpinnerData(SpinnerData annotation) {
        // 注意类型强制转换
        EasyExcelSpinnerDataSupplier bean = (EasyExcelSpinnerDataSupplier) KnifeSpringUtil.getBean(annotation.supplierBeanClass());
        return bean.easyExcelSpinnerData();
    }

    private void createValidation(WriteSheetHolder writeSheetHolder, Field field, int firstRow, String[] optionals) {
        // 获取导出的头字段
        Collection<String> includeColumnFieldNames = writeSheetHolder.getExcelWriteHeadProperty().getHeadMap().values().stream().map(Head::getFieldName).collect(Collectors.toList());
        // 获取需要填充的列
        int tempIndex = -1;
        for (String next : includeColumnFieldNames) {
            if (field.getName().equals(next)) {
                break;
            }
            tempIndex++;
        }
        // 当未匹配到导出的列时，本次不做处理
        if (tempIndex == -1) {
            return;
        }
        // 填充下拉框
        CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(firstRow, 1048575, tempIndex + 1, tempIndex + 1);
        DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper();
        DataValidationConstraint constraint = helper.createExplicitListConstraint(optionals);
        DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
        // 处理Excel兼容性问题
        if (dataValidation instanceof XSSFDataValidation) {
            dataValidation.setSuppressDropDownArrow(true);
            dataValidation.setShowErrorBox(true);
        } else {
            dataValidation.setSuppressDropDownArrow(false);
        }
        writeSheetHolder.getSheet().addValidationData(dataValidation);
    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        if (Objects.isNull(templateClass)) {
            return;
        }
        List<Field> spinnerDataAnnotationList = FieldUtils.getFieldsListWithAnnotation(templateClass, SpinnerData.class);
        if (CollectionUtils.isNotEmpty(spinnerDataAnnotationList)) {
            // 需要处理下拉框
            for (Field item : spinnerDataAnnotationList) {
                item.setAccessible(true);
                SpinnerData annotation = item.getAnnotation(SpinnerData.class);
                String[] optionals = readySpinnerData(annotation);
                // 如果属性超过255个字符，需要提示使用引用方式
                if (String.join(",", optionals).length() > 255) {
                    throw new RuntimeException("数据源超过255个字符，请联系管理员");
                }
                createValidation(writeSheetHolder, item, annotation.firstRow(), optionals);
            }
        }
    }

}
